package com.tssup.fesco.common.config.common;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;

import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DruidConfiguration {
	
	@Value("${datasource.druid.loginUsername}")
	private String loginUsername;
	
	@Value("${datasource.druid.loginPassword}")
	private String loginPassword;

    @Value("${spring.datasource.testWhileIdle}")
    private Boolean testWhileIdele;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private Integer maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.maxWait}")
    private Integer maxWaits;

    @Value("${spring.datasource.minIdle}")
    private Integer minIdle;

    @Value("${spring.datasource.maxActive}")
	private Integer maxActive;

    @Value("${datasource.druid.filters}")
    private String filters;

    @Value("${datasource.druid.session-stat-enable")
    private String sessionStatEnable;

    @Value("${datasource.druid.sessionStatMaxCount}")
    private String sessionStatMaxCount;

    @Value("${spring.datasource.max-open-prepared-statements}")
    private Integer maxOpenPreparedStatements;

    @Value("${datasource.druid.profileEnable}")
    private String profileEnable;


	@Bean
	public ServletRegistrationBean druidServlet() {
		StatViewServlet servlet = new StatViewServlet();
		ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "/druid/*");
		servletRegistrationBean.addInitParameter("loginUsername", loginUsername);
		servletRegistrationBean.addInitParameter("loginPassword", loginPassword);
		return servletRegistrationBean;
	}

	@Bean(initMethod = "init", destroyMethod = "close")
	public DataSource druidDataSource(
			@Value("${spring.datasource.driver-class-name}") String driver,
			@Value("${spring.datasource.url}") String url, 
			@Value("${spring.datasource.username}") String username,
			@Value("${spring.datasource.password}") String password) {
		
		DruidDataSource druidDataSource = new DruidDataSource();
		druidDataSource.setDriverClassName(driver);
		druidDataSource.setUrl(url);
		druidDataSource.setTestWhileIdle(true);
		druidDataSource.setMaxWait(maxWaits);
		druidDataSource.setMinIdle(minIdle);
		druidDataSource.setMaxActive(maxActive);
		druidDataSource.setPoolPreparedStatements(testWhileIdele);
		druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        druidDataSource.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
		druidDataSource.setUsername(username);
		druidDataSource.setPassword(password);
		List<Filter> proxyfilters = new ArrayList<Filter>();
		WallConfig wallConfig = new WallConfig();
		wallConfig.setMultiStatementAllow(true);
		WallFilter wallFilter = new WallFilter();
		wallFilter.setConfig(wallConfig);
		proxyfilters.add(wallFilter);
		druidDataSource.setProxyFilters(proxyfilters);
		try {
			druidDataSource.setFilters(filters);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return druidDataSource;
	}

	@Bean
	public FilterRegistrationBean filterRegistrationBean() {
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        Map<String, String> initParameters = Maps.newHashMap();
        initParameters.put("sessionStatMaxCount", sessionStatMaxCount);
        initParameters.put("profileEnable", profileEnable);
        initParameters.put("sessionStatEnable", sessionStatEnable);
        WebStatFilter filter = new WebStatFilter();
        filterRegistrationBean.setFilter(filter);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setInitParameters(initParameters);
		filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
		return filterRegistrationBean;
	}

}
